package com.zenithsun.common.security.csrf;

import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * HTML form without CSRF protection 漏洞处理（Medium）
 * @author JH
 * @date 2016
 */
public class CSRFTokenManager {
    /**
     * 验证不通过返回的消息
     */
    public static final String CSRF_TOKEN_VALIDATE_NOT_PASS_MESSAGE = "请求被拒绝";
	 /**
     * 表单input[hidden] token值的 PARAM_NAME
     */
	public static final String CSRF_TOKEN_FOR_FORM_PARAM_NAME = "CSRF_TOKEN_FOR_FORM_PARAM_NAME";
    /**
     * session的token值attribute name
     */
    public static final String CSRF_TOKEN_FOR_SESSION_ATTR_NAME = "CSRF_TOKEN_FOR_SESSION_ATTR_NAME.token";
    /**
     * 获取session的token
     * @param session
     * @return
     */
    public static String getTokenForSession(HttpSession session) {
        String token;
        synchronized (session) {
            token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME);
            if (null == token) {
                token = createToken();
                session.setAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME, token);
            }
        }
        return token;
    }
    /**
     * 获取表单input[hidden]的token
     * 
     * @param request
     * @return
     */
    public static String getTokenFromRequest(HttpServletRequest request) {
        return request.getParameter(CSRF_TOKEN_FOR_FORM_PARAM_NAME)==
        		null ? "" : request.getParameter(CSRF_TOKEN_FOR_FORM_PARAM_NAME);
    }

    /**
     * 生成token值
     * @return
     */
    public static String createToken() {
        return "token."+UUID.randomUUID().toString();
    }

    /**
     * 验证session,form的token是否一致
     * @param request
     * @return
     */
    public static boolean validateToken(HttpServletRequest request){
    	// TODO 验证token是否相等，相等返回true
        return getTokenFromRequest(request).equals(getTokenForSession(request.getSession()));
    }
    /**
     * 验证并抛出异常
     * @param request
     * @throws Exception
     */
    public static void validateForm(HttpServletRequest request) throws CSRFTokenException{
    	// TODO 验证接收的表单是否存在 [HTML form without CSRF protection]
    	if(!validateToken(request)){
    		throw new CSRFTokenException();
    	}
    }

    /**
     *
     */
    private CSRFTokenManager() {
    }
}
